package com.farvin.gis.method;

import java.lang.reflect.Field;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.farvin.gis.bean.request.AbstractRequestBean;
import com.farvin.gis.bean.request.LoginRequestBean;
import com.farvin.gis.bean.request.LogoutRequestBean;

/**
 * 请求方法工厂类，调用相应方法获取各个请求的实例
 * @author FLF
 *
 */
public class MethodFactory {
	private static MethodFactory methodFactory = null;
	private static Map<String,Class<? extends AbstractMethod>> methodMap = new HashMap<String,Class<? extends AbstractMethod>>();
	private static Map<String,Class<? extends AbstractRequestBean>> beanMap = new HashMap<String,Class<? extends AbstractRequestBean>>();
	
	
	/**
	 * 私有构造方法
	 */
	private MethodFactory(){
		registMethod();
		registBean();
	}
	
	/**
	 * 获取接口调用方法工厂类
	 * @return
	 */
	public static MethodFactory getMethodFactory(){
		if(methodFactory==null){
			methodFactory = new MethodFactory();
		}
		return methodFactory;
	}
	
	/**
	 * 根据方法名获取方法的实例
	 * @param methodName
	 * @return
	 */
	public AbstractMethod getMethod(String methodName){
		Class<? extends AbstractMethod> methodClass = methodMap.get(methodName);
		if(methodClass==null){
			System.out.println("请求："+methodName+"尚未注册！");
			return null;
		}else{
			try {
				return methodClass.newInstance();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return null;
	}
	
	/**
	 * 将请求参数封装成实体
	 * @param methodName
	 * @param req
	 * @return
	 */
	public AbstractRequestBean getRequestBean(String methodName,HttpServletRequest req){
		Class<? extends AbstractRequestBean> beanClass = beanMap.get(methodName);
		if(beanClass==null){
			System.out.println("请求："+methodName+"对应的实体类尚未注册！");
			return null;
		}else{
			AbstractRequestBean bean = null;
			try {
				bean = beanClass.newInstance();
				Map<String,Field> beanFields= getBeanFields(bean);
				@SuppressWarnings("unchecked")
				Enumeration<String> paramEnum = req.getParameterNames();
				while(paramEnum.hasMoreElements()){
					String name = paramEnum.nextElement();
					if(beanFields.containsKey(name)){
						String param = req.getParameter(name);
						setFieldVal(bean,param,beanFields.get(name));
					}
				}
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return bean;
		}
	}
	
	/**
	 * 获取请求实体的属性，包括父类的
	 * @param bean
	 * @return
	 */
	private Map<String,Field> getBeanFields(AbstractRequestBean bean){
		Map<String,Field> beanFields = new HashMap<String,Field>();
		for(Class<?> clazz = bean.getClass();clazz!=Object.class;clazz = clazz.getSuperclass()){
			Field[] fields = clazz.getDeclaredFields();
			for(Field field : fields){
				beanFields.put(field.getName(),field);
			}
		}
		return beanFields;
	}
	
	/**
	 * 为指定对象的属性设值
	 * @param bean		对象实体
	 * @param strVal	字符串值
	 * @param field		属性
	 * @throws NumberFormatException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	private void setFieldVal(Object bean,String strVal,Field field) throws NumberFormatException, IllegalArgumentException, IllegalAccessException{
		Class<?> fieldType = field.getType();
		field.setAccessible(true);
		if(fieldType.equals(String.class)){
			field.set(bean, strVal);
			return;
		}
		if(fieldType.equals(int.class) || fieldType.equals(Integer.class)){
			field.setInt(bean, Integer.parseInt(strVal));
			return;
		}
		if(fieldType.equals(long.class) || fieldType.equals(Long.class)){
			field.setLong(bean, Long.parseLong(strVal));
			return;
		}
		if(fieldType.equals(double.class) || fieldType.equals(Double.class)){
			field.setDouble(bean, Double.parseDouble(strVal));
			return;
		}
		if(fieldType.equals(short.class) || fieldType.equals(Short.class)){
			field.setShort(bean, Short.parseShort(strVal));
			return;
		}
		if(fieldType.equals(float.class) || fieldType.equals(Float.class)){
			field.setFloat(bean, Float.parseFloat(strVal));
			return;
		}
		if(fieldType.equals(byte.class) || fieldType.equals(Byte.class)){
			field.setByte(bean, Byte.parseByte(strVal));
			return;
		}
	}
	
	/**
	 * 注册  接口调用方法
	 */
	private void registMethod(){
		System.out.println("注册  接口调用方法：开始");
		methodMap.put(MethodConst.LOGIN, LoginMethod.class);
		methodMap.put(MethodConst.LOGOUT, LogoutMethod.class);
		System.out.println("注册  接口调用方法：结束");
	}
	
	/**
	 * 注册  接口请求实体类
	 */
	private void registBean(){
		System.out.println("注册  接口请求实体类：开始");
		beanMap.put(MethodConst.LOGIN, LoginRequestBean.class);
		beanMap.put(MethodConst.LOGOUT, LogoutRequestBean.class);
		System.out.println("注册  接口请求实体类：结束");
	}
}